package com.example.viewmodel_lifecycle_livedata.livedata

import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.Observer

import com.example.viewmodel_lifecycle_livedata.R
const val TAG = "LiveDataActivity"
/**


 1.数据倒灌问额：数据再次回灌回来，导致数据重复
 2.原因：
 (1)mVersion(livedta的，只要调用setValue，值+1)
 (2)mLastVersion（是observer，当onChanged接受数据，值等于mVersion）
 (3)数据如何更新？
    a。setValue():mVersion++->considerNotify
    b。considerNotify():判断mVersion和mLastversion的值
        mLastVersion >= mVersion :retrun 不执行
        mLastVersion < mVersion: mLastVersion = mVersion，触发onchange方法
（4）举例
                      mVersion：0     mLastVersion：0
 第一次请求数据setValue      1               0
 触发onChange接受           1               1
 第二次请求数据setValue      2               1
 触发onChange接受           2               2
 屏幕旋转                   2               0      解释：mVersion是livedata，livedata是viewmodel，屏幕旋转mVersion不会变
 触发onChange接受（不正常、数据倒灌）
 (5)为什公屏幕旋转mVersion不会变，mlastVersion会变为-1
 一般情况livedata结合viewmodel使用，屏幕旋转viewmodel会保留之前的数据，livedata不会改变，mVersion不会改变。
 但是mlastVersion是observer的，屏幕旋转会创建新的oberser，变为-1。 mLastVersion < mVersion产生数据倒灌
 3.解决方案：
  （1）通过反射hook技术动态修改mLastVersion
  （2）针对每一个Observer，都设置一个对应的AtomicBoolean值，LiveData执行setValue时置为true，执行onChanged后置为false，确保一个value只分发一次。

 4.setValue和postValue区别
 setValue：主线程 postValue：子线程，上锁
 5.连续100次的setValue和postValue
 setValue：100次就会有100次的接受
 postValue：100次只会有1次接受

 */
class LiveDataActivity : AppCompatActivity() {

    private val myViewModel:MyViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_live_data)
        //订阅livedata，数据发生改变，就会触发
        myViewModel.mData.observe(this, object: Observer<String> {
            override fun onChanged(value: String) {
                Log.d(TAG, "onChanged: "+value)
            }
        })
    }

    fun add(view: View) {
        //发起网络请求
        myViewModel.getNetData()
    }

}